/**
 * 本测试文件是进行对redis消息队列的吞吐量承受能力进行测试
 * 测试思路：
 *      1.对服务器进行正常连接，（服务器只启动一个，对单个服务器进行压力测试）
 *      2.启动一个客户端，这里选的是ID为1的账号，作为接收客户端
 *      3.测试程序循环发送指定数量的数据包，该数据包是相当于跨服务器聊天的数据包，需要通过服务器中redis消息队列关注的通道进行接收
*/

#include <sys/socket.h>
#include "json.hpp"
#include <iostream>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

#include <chrono>

using std::string;
using std::cout;
using std::endl;
using std::cerr;





//获取系统时间（聊天时需要添加时间信息）
string getCurrentTime(){
    auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    struct tm*ptm=localtime(&tt);
    char date[60]={0};
    sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
            (int)ptm->tm_year+1900,(int)ptm->tm_mon+1,(int)ptm->tm_mday,
            (int)ptm->tm_hour,(int)ptm->tm_min,(int)ptm->tm_sec);
    return std::string(date);
}



int main(int argc ,char* argv[]){
    if(argc<3){
        cout<<"argc error , must input LOOP_NUM and uSeconds;\n输入方式：./tmsg 发送消息次数 间隔(毫秒单位)"<<endl;
        exit(-1);
    }

    //循环发送消息次数
    const int LOOP_NUM=atoi(argv[1]);
    const int USECONDS=atoi(argv[2]);
    cout<<"LOOP_NUM: "<<LOOP_NUM<<endl;
    cout<<"USECONDS: "<<USECONDS<<endl;

    //标准socket通信
    sockaddr_in addr;
    bzero(&addr,sizeof(addr));
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_family=AF_INET;
    addr.sin_port=htons(6969);

    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0){
        cerr<<"sockfd 初始化失败"<<endl;
    }

    int ret=connect(sockfd,(sockaddr*)&addr,sizeof(addr));
    if(ret<0){
        cerr<<"conn 失败"<<endl;
        close(sockfd);
        exit(-1);
    }else if(ret==0){
        cout<<"连接成功！！"<<endl;
    }

    //伪消息包，假装是id:2发给id:1的聊天数据
    

    for(int i=0;i<LOOP_NUM;++i){
        nlohmann::json js;
        js["msgid"]=5;
        js["id"]=2;
        js["name"]="test";
        js["toid"]=1;
        js["time"]=getCurrentTime();
        js["msg"]=string("test->"+std::to_string(i+1));

        string buf=js.dump();
        cout<<buf<<endl;
        ret=send(sockfd,buf.c_str(),buf.size(),0);

        if(ret<0){
            cerr<<"第"<<i+1<<"次 send 失败！"<<endl;
        }
        
        buf.clear();
        js.clear();
        
        //微妙sleep,100毫秒=100*1000
        usleep(USECONDS);
    }

    int i=0;
    std::cin>>i;
    close(sockfd);

}

/**
 * 测试结果：
 * 1、在1毫秒发送1次的消息量中，服务器承受到了第3040次（总共发送1w次）出错
 * 2、在1.5毫秒发送1次的消息量中，服务器承受了总共1w次的吞吐量
 * 
 */